<html>
<head>
<title>How to register a class object</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="highlight.css" type="text/css">
</head>

<body bgcolor="#FFFFFF" text="#000000">
<p><font size="6"><i><b>How to register a class object</b></i></font></p>
<p align="left"><font size="4">In the <a href="howto_class.html">previous HowTo</a> 
  we created a class object for the C++ class Simple. Before this class object 
  can be used by the zeitgeist framework it must be registered with a zeitgeist::Core 
  object. The Core is the object hierarchy, which is basically a virtual file 
  system where instances of classes represent the directories and 'files'. Therefore, 
  each class instance can be identified by a path. The Core has a function called 
  RegisterClassObject() which inserts the class object into the object hierarchy. 
  Class objects are located under the '/classes/' branch of the hierarchy. We 
  have two major scenarios of how a class object can be registered: Directly or 
  indirectly!</font></p>
<p align="left"><font size="4"><b>Direct Registration</b></font></p>
<p align="left"><font size="4">This scenario is used in the case of static libraries 
  and executables, which want to expose custom classes to the object hierarchy. 
  An example of a library, which does this is Kerosin. This way of registering 
  is pretty straight forward and involves an initialization function which has 
  a means to access the zeitgeist::Core instance where the class objects are to 
  be registered. Then it (directly) calls the RegisterClassObject()-method to 
  successively add class objects. Here's a short snippet from the Kerosin library:</font></p>
<pre><span class="dir">#include </span><span class="dstr">&quot;kerosin.h&quot;</span><span class="dir"></span>
<span class="dir">#include &lt;zeitgeist/scriptserver/scriptserver.h&gt;
</span>
<span class="key">using namespace </span>kerosin;
<span class="key">using namespace </span>zeitgeist;

Kerosin::Kerosin(zeitgeist::Zeitgeist &amp;zg)
{
  zg.GetCore()-&gt;RegisterClassObject(<span class="key">new </span>CLASS(SoundServer), <span class="str">&quot;kerosin/&quot;</span>);

  zg.GetCore()-&gt;RegisterClassObject(<span class="key">new </span>CLASS(InputServer), <span class="str">&quot;kerosin/&quot;</span>);

  zg.GetCore()-&gt;RegisterClassObject(<span class="key">new </span>CLASS(ImageServer), <span class="str">&quot;kerosin/&quot;</span>);

  zg.GetCore()-&gt;RegisterClassObject(<span class="key">new </span>CLASS(FontServer), <span class="str">&quot;kerosin/&quot;</span>);

  zg.GetCore()-&gt;RegisterClassObject(<span class="key">new </span>CLASS(OpenGLServer), <span class="str">&quot;kerosin/&quot;</span>);
</pre>
<p align="left"><font size="4">The Kerosin library is initialized by creating 
  an instance of the Kerosin class. The constructor needs a reference to the Zeitgeist 
  object (which represents the Zeitgeist library), so it can get access to the 
  Core. The class objects are all added to the object hierarchy under the '/classes/' 
  branch. The second parameter of RegisterClassObject() allows to specify an additional 
  subpath. So, the class object for the SoundServer (for example) will be located 
  at '/classes/kerosin/SoundServer' ... in a way, this allows to create a form 
  of namespaces among the class objects. As we can see, it is possible to add 
  a class object directly at any time during the execution of the program.</font></p>
<p align="left">&nbsp;</p>
<p align="left"><font size="4"><b>Indirect Registration</b></font></p>
<p align="left"><font size="4">The second scenario involves packaging a bunch 
  of class objects into a shared library (DLL). The DLL becomes a class library, 
  containing a collection of classes to be added to the object hierarchy. This 
  kind of DLL is referred to as a Bundle. The Bundle contains a well-defined entry 
  point function, which registers its contents with the calling Core. This (again) 
  is simplified through the use of several macros. First, we have to create a 
  DLL project, containing a bunch of classes and their corresponding class objects 
  (see the <a href="howto_class.html">previous HowTo</a>). Then, we create an 
  additional CPP file. I usually call this file export.cpp. Let's say we have 
  two classes in our bundle, Simple and Complex. The corresponding export.cpp 
  would look like this:</font></p>
<pre><span class="dir">#include </span><span class="dstr">&quot;simple.h&quot;</span><span class="dir"></span>
<span class="dir">#include </span><span class="dstr">&quot;complex.h&quot;</span><span class="dir"></span>
<span class="dir">#include &lt;zeitgeist/zeitgeist.h&gt;
</span>
ZEITGEIST_EXPORT_BEGIN()
  ZEITGEIST_EXPORT(Simple);
  ZEITGEIST_EXPORT(Complex);
ZEITGEIST_EXPORT_END()
</pre>
<p align="left"><font size="4">Thanks to the macros, this is again very easy to 
  grasp. We just include the header files of all classes we want to expose. These 
  should also incorporate the correct class object declarations. Then we include 
  the zeitgeist framework. The following macros implement the entry point function. 
  ZEITGEIST_EXPORT_BEGIN() implements the beginning of the function. Then we use 
  ZEITGEIST_EXPORT() for every class we want to export, and finally ZEITGEIST_EXPORT_END() 
  to 'terminate' the function. Now, we just compile the shared library and 'presto' 
  ... a Zeitgeist-capable Bundle has been created. The ZEITGEIST_EXPORT_EX() macro 
  can be used to specify a subpath as above with RegisterClassObject().</font></p>
<p align="left"><font size="4">To indirectly register the classes contained in 
  a Bundle, you just import the bundle into the Core. This is done with the ImportBundle()-member 
  function. This function opens the shared library. Gets the entry point function 
  and calls it with an STL list. The class objects are added to this list within 
  the entry point function. After returning, all class objects contained in this 
  list are added to the object hierarchy.</font></p>
<p align="left"><font size="4">In the <a href="howto_script.html">next HowTo</a>, 
  we will take a look at executing Ruby scripts, loading Bundles via scripts and 
  creating instances of classes via scripts.</font></p>
</body>
</html>

